'use strict';

const Controller = require('egg').Controller;
const jwt = require('jsonwebtoken');
const ObjectId = require('mongodb').ObjectId;
const crypto = require('crypto');
// 密匙
const SECRET_KEY = 'huiazir';
const TOKEN_KEY = 'azir';
class UserController extends Controller {
  // md5 加密
  md5(content) {
    const md5 = crypto.createHash('md5');
    return md5.update(content).digest('hex'); // 把输出编程16进制的格式
  }

  // 加密函数
  genPassword(password) {
    const str = `password=${password}&key=${SECRET_KEY}`; // 拼接方式是自定的，只要包含密匙即可
    return this.md5(str);
  }

  async signIn() {
    const { ctx } = this;
    const { model } = ctx;
    const { phone, password } = ctx.request.body;
    const findUser = await model.User.find({ phone });
    if (findUser.length === 0) {
      ctx.body = {
        code: -1,
        message: '该手机或邮箱不存在',
      };
    } else {
      const user = findUser[0];
      const genPwd = this.genPassword(password);
      console.log(genPwd);
      if (phone === user.phone && genPwd === user.password) {
        // 颁发token
        const token = jwt.sign({ userInfo: user }, TOKEN_KEY);
        ctx.body = {
          code: 0,
          data: {
            token,
            userInfo: {
              id: user._id,
              name: user.name,
              avatar: user.avatar,
            },
          },
        };
      } else {
        ctx.body = {
          code: -1,
          message: '密码错误，请重新登陆',
        };
      }
    }
  }

  async signUp() {
    const { ctx } = this;
    const { model } = ctx;
    try {
      const { name, password, phone, mail } = ctx.request.body;
      const findUserByName = await model.User.find({ name });
      const findUserByPhone = await model.User.find({ phone });
      if (findUserByName.length > 0) {
        ctx.body = {
          code: -1,
          message: '该用户名已被使用',
        };
      } else if (findUserByPhone.length > 0) {
        ctx.body = {
          code: -1,
          message: '该手机已被注册',
        };
      } else {
        const savePassword = this.genPassword(password);
        const res = await model.User.insertMany([
          {
            name,
            mail,
            password: savePassword,
            phone,
            avatar: '',
            i_liked: [],
            liked_me: [],
            my_followed: [],
            followed_me: [],
            favorited: [],
            messages: [],
          },
        ]);
        // 颁发token
        const token = jwt.sign({ userInfo: res[0] }, TOKEN_KEY);
        ctx.body = {
          code: 0,
          data: {
            token,
            userInfo: res[0],
          },
          message: 'ok',
        };
      }
    } catch (error) {
      ctx.body = { code: -1, message: 'server error' };
    }
  }

  async getAllUsers() {
    const { ctx } = this;
    const { model } = ctx;
    const result = await model.User.find({});
    ctx.body = {
      code: 0,
      data: result,
    };
  }

  async getLikedMessageByUserId() {
    const { ctx } = this;
    try {
      const { model } = ctx;
      const { id } = ctx.request.query;
      const result = await model.User.aggregate([
        {
          $match: {
            _id: ObjectId(id),
          },
        },
        {
          $project: {
            messages: 1,
          },
        },
        {
          $addFields: {
            messages: {
              $filter: {
                input: '$messages',
                as: 'item',
                cond: { $eq: [ '$$item.messageType', 'liked' ] },
              },
            },
          },
        },
        {
          $unwind: '$messages',
        },
        {
          $lookup: {
            from: 'user',
            localField: 'messages.fromUser',
            foreignField: '_id',
            as: 'userInfo',
          },
        },
        {
          $lookup: {
            from: 'articles',
            localField: 'messages.articleId',
            foreignField: '_id',
            as: 'articleInfo',
          },
        },
        {
          $unwind: '$userInfo',
        },
        {
          $unwind: '$articleInfo',
        },
        {
          $group: {
            _id: '$_id',
            messages: {
              $push: {
                time: '$messages.time',
                fromUser: '$messages.fromUser',
                user: '$userInfo.name',
                avatar: '$userInfo.avatar',
                articleId: '$messages.articleId',
                articleTitle: '$articleInfo.title',
              },
            },
          },
        },
      ]);
      if (result) {
        if (Array.isArray(result) && result.length > 0) {
          ctx.body = {
            code: 0,
            data: result[0].messages,
          };
        } else {
          ctx.body = {
            code: 0,
            data: [],
          };
        }
      } else {
        ctx.body = {
          code: -1,
          data: [],
        };
      }
    } catch (e) {
      console.error(e);
      ctx.body = {
        code: -1,
        message: 'service error',
      };
    }
  }

  async getCommentArticleMessageByUserId() {
    const { ctx } = this;
    try {
      const { model } = ctx;
      const { id } = ctx.request.query;
      const result = await model.User.aggregate([
        {
          $match: {
            _id: ObjectId(id),
          },
        },
        {
          $project: {
            messages: 1,
          },
        },
        {
          $addFields: {
            messages: {
              $filter: {
                input: '$messages',
                as: 'item',
                cond: { $in: [ '$$item.messageType', [ 'commentArticle', 'commentReply' ]] },
              },
            },
          },
        },
        {
          $unwind: '$messages',
        },
        {
          $lookup: {
            from: 'user',
            localField: 'messages.fromUser',
            foreignField: '_id',
            as: 'userInfo',
          },
        },
        {
          $lookup: {
            from: 'articles',
            localField: 'messages.articleId',
            foreignField: '_id',
            as: 'articleInfo',
          },
        },
        {
          $unwind: '$userInfo',
        },
        {
          $unwind: '$articleInfo',
        },
        {
          $group: {
            _id: '$_id',
            messages: {
              $push: {
                time: '$messages.time',
                fromUser: '$messages.fromUser',
                content: '$messages.content',
                messageType: '$messages.messageType',
                user: '$userInfo.name',
                avatar: '$userInfo.avatar',
                articleId: '$messages.articleId',
                articleTitle: '$articleInfo.title',
              },
            },
          },
        },
      ]);
      if (result) {
        if (Array.isArray(result) && result.length > 0) {
          ctx.body = {
            code: 0,
            data: result[0].messages,
          };
        } else {
          ctx.body = {
            code: 0,
            data: [],
          };
        }
      } else {
        ctx.body = {
          code: -1,
          data: [],
        };
      }
    } catch (e) {
      console.error(e);
      ctx.body = {
        code: -1,
        message: 'service error',
      };
    }
  }

  async getFocusMessageByUserId() {
    const { ctx } = this;
    try {
      const { model } = ctx;
      const { id } = ctx.request.query;
      const result = await model.User.findOne(
        {
          _id: id,
        },
        {
          messages: 1,
        }
      );
      if (result) {
        let messages = Array.isArray(result.messages) ? result.messages : [];
        messages = messages.filter(
          message => message.messageType === 'focus'
        );
        ctx.body = {
          code: 0,
          data: messages,
        };
      } else {
        ctx.body = {
          code: -1,
          data: [],
        };
      }
    } catch (e) {
      console.error(e);
      ctx.body = {
        code: -1,
        message: 'service error',
      };
    }
  }

  async getSystemMessageByUserId() {
    const { ctx } = this;
    try {
      const { model } = ctx;
      const { id } = ctx.request.query;
      const result = await model.User.findOne(
        {
          _id: id,
        },
        {
          messages: 1,
        }
      );
      if (result) {
        let messages = Array.isArray(result.messages) ? result.messages : [];
        messages = messages.filter(
          message => message.messageType === 'system'
        );
        ctx.body = {
          code: 0,
          data: messages,
        };
      } else {
        ctx.body = {
          code: -1,
          data: [],
        };
      }
    } catch (e) {
      console.error(e);
      ctx.body = {
        code: -1,
        message: 'service error',
      };
    }
  }
}

module.exports = UserController;
